package com.neucloud.da.edgeside.filter;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.neucloud.da.edgeside.constant.SecurityConstants;
import com.neucloud.da.edgeside.model.constant.Result;
import com.neucloud.da.edgeside.model.constant.SecurityCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;


@Slf4j
@Component
public class ApiSignFilter implements HandlerInterceptor {

    @Autowired
    RedisTemplate redisTemplate;

    @Value("${api.sign.expireTimeMinutes}")
    long expireTimeMinutes;

    @Value("${api.sign.repeatTimeSeconds}")
    long repeatTimeSeconds;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String requestURI = request.getRequestURI();
        if(requestURI.indexOf("online-") <= 0){
            return true;
        }

        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

//        //服务访问密钥
//        String appId = request.getHeader(SecurityConstants.ACCESS_KEY);

        //分配的应用id
        String appId = request.getHeader(SecurityConstants.APP_ID);
        if (StrUtil.isBlank(appId)) {
            response.getWriter().write(JSON.toJSONString(Result.failed(SecurityCode.SIGN_NO_APP_ID, SecurityCode.SIGN_NO_APP_ID.getMsg())));
            return false;
        }

        //时间戳
        String timestampStr = request.getHeader(SecurityConstants.TIMESTAMP);
        if (StrUtil.isBlank(timestampStr)) {
            response.getWriter().write(JSON.toJSONString(Result.failed(SecurityCode.SIGN_NO_TIMESTAMP, SecurityCode.SIGN_NO_TIMESTAMP.getMsg())));
            return false;
        }

        //时间戳
        String nonce = request.getHeader(SecurityConstants.NONCE);
        if (StrUtil.isBlank(nonce)) {
            response.getWriter().write(JSON.toJSONString(Result.failed(SecurityCode.SIGN_NO_NONCE, SecurityCode.SIGN_NO_NONCE.getMsg())));
            return false;
        }

        //签名
        String signature = request.getHeader(SecurityConstants.SIGNATURE);
        if (StrUtil.isBlank(timestampStr)) {
            response.getWriter().write(JSON.toJSONString(Result.failed(SecurityCode.SIGN_NO_SIGN, SecurityCode.SIGN_NO_SIGN.getMsg())));
            return false;
        }

        //根据时间戳判断是否过期,超过规定时间判定其无效
        long timestamp = Long.parseLong(timestampStr);
        if (Math.abs((timestamp - System.currentTimeMillis()) / 1000) > (expireTimeMinutes * 60)) {
            response.getWriter().write(JSON.toJSONString(Result.failed(SecurityCode.SIGN_TIMESTAMP_INVALID, SecurityCode.SIGN_TIMESTAMP_INVALID.getMsg())));
            return false;
        }

        //从redis中检查是否有nonce这个子段，如果有直接失败,没有的话则设置一个k-v存入redis中，设置过期时间，这样就保证了短时间内不会被再次调用
        Object redisTimeStampStr = redisTemplate.opsForValue().get(nonce);
        if (redisTimeStampStr != null) {
            response.getWriter().write(JSON.toJSONString(Result.failed(SecurityCode.SIGN_DUPLICATION, SecurityCode.SIGN_DUPLICATION.getMsg())));
            return false;
        } else {
            redisTemplate.opsForValue().set(nonce, timestampStr, repeatTimeSeconds, TimeUnit.SECONDS);
            return true;
        }




//        //获取服务访问密钥
//        String appId = request.getHeader(SecurityConstants.ACCESS_KEY);
//
//
//        //拼接数据
//        String origin = appId + "\n" + appSecret + "\n" + timestampStr;
//        if (!SignatureUtils.verify(appSecret, origin, signature)) {
//            response.setStatus(500);
//            response.getWriter().println("签名错误!");
//            return false;
//        }


    }





//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        ServerHttpRequest request = exchange.getRequest();
//        RequestPath path = exchange.getRequest().getPath();
//        String uri = path.pathWithinApplication().value();
//        String pattern = "/api-artifact/prodspace/online/service/.*?/apis/.*?";
//        String modelPattern = "/api-artifact/prodspace/online/model/.*?/apis/.*?";
//        Boolean isModel = false;
//        if((!Pattern.matches(pattern, uri)) && (!(Pattern.matches(modelPattern, uri)))){
//            return chain.filter(exchange);
//        }
//        if(Pattern.matches(modelPattern, uri)){
//            isModel = true;
//        }
//
//
//        if (request == null) {
//            return illgeal(exchange, ResponseCode.SIGN_REQUEST_GET_FAILED);
//        }
//        MultiValueMap<String, String> queryParams = request.getQueryParams();
//
//        //accessKey是否存在
//        String accessKey = queryParams.getFirst("accessKey");
//        if (StringUtils.isBlank(accessKey)) {
//            return illgeal(exchange, ResponseCode.SIGN_NO_ACCESS_KEY);
//        }
//
//        //serviceId是否存在
////        String serviceIdstr = queryParams.getFirst("serviceId");
////        if (StringUtils.isBlank(serviceIdstr)) {
////            return illgeal(exchange, ResponseCode.SIGN_NO_SERVICE_ID);
////        }
////        Long serviceId = Long.parseLong(serviceIdstr);
//
//        //timestamp是否存在
//        String timestampStr = queryParams.getFirst("timestamp");
//        if (StringUtils.isBlank(timestampStr)) {
//            return illgeal(exchange, ResponseCode.SIGN_NO_TIMESTAMP);
//        }
////
//        //签名字段syn是否存在
//        String sign = queryParams.getFirst("sign");//前端传来的签名
//        if (StringUtils.isBlank(sign)) {
//            return illgeal(exchange, ResponseCode.SIGN_NO_SIGN);
//        }
//
//        //唯一字符串nonce是否存在
//        String nonce = queryParams.getFirst("nonce");
//        if (StringUtils.isBlank(nonce)) {
//            return illgeal(exchange, ResponseCode.SIGN_NO_NONCE);
//        }
//
//        // ************* 逻辑校验 ***************
//        //根据时间戳判断是否过期,超过规定时间判定其无效
//        long timestamp = Long.parseLong(timestampStr);
//        if (Math.abs((timestamp - System.currentTimeMillis()) / 1000) > (expireTimeMinutes * 60)) {
//            return illgeal(exchange, ResponseCode.SIGN_TIMESTAMP_INVALID);
//        }
//
//        //从redis中检查是否有nonce这个子段，如果有直接失败,没有的话则设置一个k-v存入redis中，设置过期时间，这样就保证了短时间内不会被再次调用
//        Object redisTimeStampStr = redisTemplate.opsForValue().get(nonce);
//        if (redisTimeStampStr != null) {
//            return illgeal(exchange, ResponseCode.SIGN_DUPLICATION);
//        } else {
//            redisTemplate.opsForValue().set(nonce, timestampStr, repeatTimeSeconds, TimeUnit.SECONDS);
//        }
//
//        String secretKey = artifactService.getSecretKey(accessKey, isModel);
//        if(secretKey==null){
//            return illgeal(exchange, ResponseCode.SIGN_WRONG_SERVICE_ID);
//        }
//        String curSign = DigestUtils.md5Hex(accessKey + secretKey + timestampStr + nonce);
//        //String curSign = DigestUtils.md5Hex(accessKey + serviceIdstr + secretKey);
//        if (!curSign.equals(sign)) {
//            return illgeal(exchange, ResponseCode.SIGN_VERIFY_FAIL);
//        }
//
//
//        return chain.filter(exchange);
//
//
//    }

}
